<?php

namespace App\Models;

use Carbon\Carbon;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Dcat\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\Sortable;

class Project extends Model implements Sortable
{
    use ModelTree, HasDateTimeFormatter;
    use HasFactory;

    // 设置排序字段，默认order
    protected $orderColumn = 'order';

    protected $fillable = [
        "title",
        "is_show",
        "parent_id",
        "department_id",
        "depth",
        "order",
        "limit_count",
        "time_interval",
        "project_time",
        "time_range",
    ];

    public function reservation(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
    {
        return $this->belongsToMany(ReservationLog::class, 'reservation_has_project', 'project_id', 'reservation_id');
    }

    public function extraInfo(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(ProjectHasExtra::class, "project_id", "id");
    }

    public function childrenRelation(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(self::class, 'parent_id', 'id');
    }

    /**
     * @param array $projects
     * @param Carbon $date
     * @param array|null $excludeReservation
     * @return \Illuminate\Database\Eloquent\Collection|array
     */
    public static function getProjectsAndDetail(array $projects, Carbon $date, array $excludeReservation = null): \Illuminate\Database\Eloquent\Collection|array
    {
        return Project::query()
            ->with([
                'extraInfo' => function ($query) use ($date) {
                    $query->where('enable', 1)
                        ->where(function ($query) use ($date) {
                            // 如果 status = 0，直接返回记录
                            $query->where('day_type', 0)
                                // 如果 status = 1，检查 start_date 和 end_date 是否包含指定日期
                                ->orWhere(function ($query) use ($date) {
                                    $query->where('day_type', 1)
                                        ->whereDate('start_date', '<=', $date)
                                        ->whereDate('end_date', '>=', $date);
                                });
                        })
                        ->orderBy("time_type")
                        ->orderBy("id", 'desc');
                },
                "reservation" => function ($query) use ($date, $excludeReservation) {
                    $query->whereDate('date', $date);
                    if ($excludeReservation) {
                        $query->whereNotIn('id', $excludeReservation);
                    }
                }
            ])
            ->where('time_interval', "<>", 0)
            ->where('is_show', 1)
            ->whereIn('id', $projects)
            ->orderBy('order')
            ->get();
    }

    public static function twoLevelOptions()
    {
        $c = self::query()
            ->where('depth', '<=', 2)
            ->get();

        $options = (new static())->buildSelectOptions($c->toArray());
        return collect($options)->all();
    }

    public static function oneLevelOptions($rootText = null, bool $showRoot = true)
    {
        $c = self::query()
            ->where('depth', '=', 1)
            ->get();
        $rootText = $rootText ?: admin_trans_label('root');

        $options = (new static())->buildSelectOptions($c->toArray());
        $options = collect($options);
        if ($showRoot)
            $options = $options->prepend($rootText, 0);
        return $options->all();
    }

    /**
     * 获取 治疗项目 的时段数组
     * @return array
     */
    public function getTimeGroupAttribute(): array
    {
        if (!$this->time_interval || !$this->parent_id) return [];
        return splitTimeIntervals($this->time_interval);
    }

    public function getTimeResult($date): self
    {
        if ($this->timeResult) {
            return $this;
        }
        $timeGroup = $this->time_group;
        $timeResult = [];

        foreach ($timeGroup as $time) {
            $extra = Project::checkExtraIsMatch($this->extraInfo, $time, $date);
            if ($extra) {
                if ($extra->extra_type) {
                    $timeResult[$time] = $extra->up;
                } else
                    $timeResult[$time] = 0;
            } else
                $timeResult[$time] = $this->limit_count;
        }
        if ($this->reservation) {
            foreach ($this->reservation as $item) {
                foreach ($timeResult as $timeKey => $timeValue) {
                    if (hasOverlap($timeKey, $item->time)) {
                        $timeResult[$timeKey] -= 1;
                    }
                }
            }
        }

        $this->timeResult = $timeResult;
        return $this;
    }

    /**
     * 查看是否匹配额外治疗设置
     * @param $extraList
     * @param $time
     * @param $date
     * @return null
     */
    public static function checkExtraIsMatch($extraList, $time, $date = null)
    {
        if (!$extraList) return null;
        foreach ($extraList as $extra) {
            if ($extra->checkTimeIsBlock($time, $date)) {
                return $extra;
            }
        }
        return null;
    }

    public static function getFullResourceOptions()
    {
        /**
         * {
         * "id": "c",
         * "title": "Auditorium C",
         * "eventColor": "orange"
         * },
         * {
         * "id": "d",
         * "title": "Auditorium D",
         * "children": [
         * {
         * "id": "d1",
         * "title": "Room D1"
         * },
         * {
         * "id": "d2",
         * "title": "Room D2"
         * }
         * ]
         * },
         */

        $projects = Project::query()
            ->where('is_show', 1)
            ->get()
            ->map(function ($item) {
                $title = $item->title;
                $parent_id = $item->parent_id;
                if ($parent_id)
                    $title .= "({$item->project_time}分钟)";
                return [
                    "id" => $item->id,
                    "parent_id" => $parent_id,
                    "title" => $title,
                ];
            });

        return buildTree($projects->toArray(),0);

    }


}
